use clap::Parser;
use std::thread::available_parallelism;
use std::{env, io};
use vch::cli::{Cli, Commands};
#[allow(unused_imports)]
use vch::context::{init_error_hooks, CONTEXT};
use vch::module::upgrade;
use vch::module::version_cmd;

// Initialize i18n
rust_i18n::i18n!("locales", fallback = "en");

fn main() {
    println!("{:?}", CONTEXT.to_string());
    init();
    let cli = match Cli::try_parse() {
        Ok(cli) => cli,
        Err(e) => {
            // if the error is not printed to stderr, this means it was not really
            // an error but rather some information is going to be listed, therefore
            // we won't print the arguments passed
            let is_info_only = !e.use_stderr();
            // print the error and void panicking in case of stdout/stderr closing unexpectedly
            let _ = e.print();
            // if there was no mistake by the user and we're only going to display information,
            // we won't put arguments or exit with non-zero code
            let exit_code = if is_info_only {
                0
            } else {
                // print the arguments
                // avoid panicking in case of stderr closing
                let mut stderr = io::stderr();
                use io::Write;
                let _ = writeln!(
                    stderr,
                    "\nNOTE:\n    passed arguments: {:?}",
                    // collect into a vec to format args as a slice
                    env::args().skip(1).collect::<Vec<_>>()
                );
                // clap exits with status 2 on error:
                //  https://docs.rs/clap/latest/clap/struct.Error.html#method.exit
                2
            };
            std::process::exit(exit_code);
        }
    };
    match cli.command {
        Commands::Config(_) => {}
        Commands::Version(args) => version_cmd::run(args),
        Commands::Source(_) => {}
        Commands::Upgrade { .. } => upgrade::run(),
        #[cfg(test)]
        Commands::Test => {
            print!("{}", CONTEXT.to_string());
        }
        #[allow(unreachable_patterns)]
        _ => {}
    }
}

fn init() {
    #[cfg(windows)]
    let _ = nu_ansi_term::enable_ansi_support();

    // 获取环境变量 LANG，如果不存在则使用默认值 "en"
    let lang = env::var("LANG").unwrap_or_else(|_| "en_US.UTF-8".to_string());

    // 解析 LANG 变量，提取语言部分
    let locale = if let Some((lang_part, _)) = lang.split_once('.') {
        lang_part.replace("_", "-").to_string()
    } else {
        "en".to_string()
    };
    // 设置 locale
    rust_i18n::set_locale(&*locale);

    // 初始化线程池
    init_global_thread_pool();
    init_error_hooks().unwrap();
}

fn init_global_thread_pool() {
    // Allow overriding the number of threads
    let num_threads = env::var("NUM_THREADS")
        .ok()
        .and_then(|s| s.parse().ok())
        // Default to the number of logical cores,
        // but restrict the number of threads to 8
        .unwrap_or_else(|| available_parallelism().map(usize::from).unwrap_or(1).min(8));

    rayon::ThreadPoolBuilder::new()
        .num_threads(num_threads)
        .build_global()
        .expect("Failed to initialize worker thread pool");
}
